<template>
  <el-card
    v-if="OTHER_TASK_NAME_ARRAY.includes((controlData.workflow || {}).taskName)"
  >
    <div slot="header">
      <span>发票清单</span>
    </div>
    <div class="invoice-content">
      <div>
        <vxe-toolbar>
          <template #buttons>
            <div class="amount-content">
              金额合计：
              <span style="color: red">
                {{ invoiceTotalAmount | formatAmount }}元
              </span>
            </div>
            <el-select
              v-model="taxRate"
              placeholder="默认扫描税率"
              style="max-width: 120px; margin-right: 10px"
            >
              <el-option
                v-for="item in TAX_RATE_OPTION"
                :key="item.value"
                :label="item.key"
                :value="item.value"
              ></el-option>
            </el-select>
            <el-button
              v-if="!enabledParse"
              type="primary"
              size="small"
              @click="onEnabledAutoParse(true)"
              >开启自动扫描</el-button
            >
            <el-button
              v-if="enabledParse"
              type="danger"
              size="small"
              @click="onEnabledAutoParse(false)"
              >关闭自动扫描</el-button
            >
            <el-button
              type="primary"
              size="small"
              @click="handleDupInvoiceCheck"
              >重复发票核验</el-button
            >
            <el-button type="primary" size="small" @click="onAdd">
              添加
            </el-button>
            <el-button type="primary" size="small" @click="onQuickAdd">
              快速添加
            </el-button>
          </template>
        </vxe-toolbar>

        <vxe-table
          ref="invoiceTableRef"
          :data="invoices"
          :highlight-current-row="true"
          :highlight-hover-row="true"
          :highlight-current-column="true"
          :highlight-hover-column="true"
          :auto-resize="true"
          align="center"
        >
          <vxe-column type="seq" width="60" title="序号" show-overflow />
          <vxe-column field="invoiceCode" title="发票代码" show-overflow />
          <vxe-column field="invoiceNum" title="发票号码" show-overflow>
            <template #default="{ row }">
              <div :style="row.isRepetitionInvoiceNum ? { color: 'red' } : {}">
                {{ row.invoiceNum }}
              </div>
            </template>
          </vxe-column>
          <vxe-column
            field="invoiceDate"
            title="开票日期"
            :formatter="formatDate"
            show-overflow
          />
          <vxe-column
            field="invoiceAmount"
            title="发票金额"
            :formatter="formatAmount"
            show-overflow
          />
          <vxe-column field="taxRate" title="税率" show-overflow>
            <template #default="{ row }">
              <el-select
                :value="row.taxRate"
                placeholder="税率"
                style="max-width: 120px"
                @change="changeTaxRate($event, row)"
              >
                <el-option
                  v-for="item in TAX_RATE_OPTION"
                  :key="item.value"
                  :label="item.key"
                  :value="item.value"
                ></el-option>
              </el-select>
            </template>
          </vxe-column>
          <vxe-column
            field="remark"
            title="备注"
            show-overflow
            :edit-render="{ name: 'input' }"
          />
          <vxe-column title="操作" width="150" show-overflow>
            <template #default="{ row, rowIndex }">
              <el-button
                icon="fa fa-edit"
                type="text"
                size="mini"
                @click="onEditInvoice(row, rowIndex)"
              >
                编辑
              </el-button>
              <el-button
                icon="fa fa-trash-o"
                type="text"
                size="mini"
                :style="row.isRepetitionInvoiceNum ? { color: 'red' } : {}"
                @click="onRemoveInvoice(rowIndex)"
              >
                删除
              </el-button>
            </template>
          </vxe-column>
        </vxe-table>
      </div>
    </div>

    <vxe-modal
      v-model="modalVisible"
      :resize="true"
      width="500"
      :height="addInvoiceModel === COMMON_ADD_INVOICE_MODEL ? '395' : '200'"
      title="发票清单"
      show-zoom
      destroy-on-close
      :show-footer="true"
      @close="onModalClose"
      @show="onModalShow"
      :loading="modalLoading"
    >
      <el-form
        ref="invoiceFormRef"
        label-position="left"
        :model="invoiceModel"
        :rules="invoiceRules"
        :label-width="'80px'"
      >
        <el-form-item
          v-if="addInvoiceModel === COMMON_ADD_INVOICE_MODEL"
          label="发票代码"
          prop="invoiceCode"
        >
          <el-input
            v-model="invoiceModel.invoiceCode"
            placeholder="请输入发票代码"
          />
        </el-form-item>
        <el-form-item
          v-if="addInvoiceModel === COMMON_ADD_INVOICE_MODEL"
          label="开票日期"
          prop="invoiceDate"
        >
          <el-date-picker
            v-model="invoiceModel.invoiceDate"
            clearable
            size="small"
            type="date"
            value-format="yyyy-MM-dd"
            placeholder="请选择开票日期"
          />
        </el-form-item>
        <el-form-item label="发票号码" prop="invoiceNum">
          <el-input
            ref="invoiceNumRef"
            v-model="invoiceModel.invoiceNum"
            placeholder="请输入发票号码"
          />
        </el-form-item>
        <el-form-item label="发票金额" prop="invoiceAmount">
          <el-input-number
            v-model="invoiceModel.invoiceAmount"
            :controls="false"
            :precision="2"
            placeholder="请输入发票金额"
            @keyup.enter.native="onInvoiceAmountEntity"
          />
        </el-form-item>
        <el-form-item
          v-if="addInvoiceModel === COMMON_ADD_INVOICE_MODEL"
          label="备注"
          prop="remark"
        >
          <el-input v-model="invoiceModel.remark" placeholder="请输入备注" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button
          v-if="addInvoiceModel === COMMON_ADD_INVOICE_MODEL"
          type="primary"
          @click="onModalConfirm"
        >
          确定
        </el-button>
        <el-button type="info" @click="onModalCancel">
          {{ addInvoiceModel === COMMON_ADD_INVOICE_MODEL ? "取消" : "关闭" }}
        </el-button>
      </template>
    </vxe-modal>
  </el-card>
</template>

<script>
import request from "@/utils/request";
import Util from "@/libs/framework/util";

// 发票分割标识默认是中文的逗号
const INVOICE_SPLIT_KEY = "，";
// 发票根据分割标识分割后的长度，经测试为9【需验证】。
const INVOICE_SPLIT_LENGTH = 9;
// 发票添加模式
const COMMON_ADD_INVOICE_MODEL = "common";
const QUICK_ADD_INVOICE_MODEL = "quick";
const TAX_RATE_DEFAULT_VALUE = 0;
const TAX_RATE_OPTION = [
  { key: "0%", value: 0 },
  { key: "1%", value: 0.01 },
  { key: "3%", value: 0.03 },
  { key: "6%", value: 0.06 },
  { key: "13%", value: 0.13 },
];
const OTHER_TASK_NAME_ARRAY = [
  "行政前台审核",
  "综合部助理审核",
  "综合部经理审批",
];

export default {
  props: {
    invoices: {
      type: Array,
      default: () => [],
    },
    controlData: {
      type: Object,
    },
  },
  data() {
    return {
      taxRate: TAX_RATE_DEFAULT_VALUE,
      modalVisible: false,
      invoiceModel: {
        invoiceCode: undefined,
        invoiceNum: undefined,
        invoiceDate: undefined,
        invoiceAmount: undefined,
        taxRate: TAX_RATE_DEFAULT_VALUE,
        remark: undefined,
      },
      beforeEditInvoice: undefined,
      invoiceRules: {
        invoiceAmount: [
          {
            required: true,
            message: "发票金额不能为空",
            trigger: "blur",
          },
        ],
      },
      invoiceTotalAmount: 0,
      rmDetailModalIsEdit: false,
      isEdit: false,
      editRowIndex: 0,
      enabledParse: false,
      originData: undefined,
      COMMON_ADD_INVOICE_MODEL,
      QUICK_ADD_INVOICE_MODEL,
      addInvoiceModel: COMMON_ADD_INVOICE_MODEL,
      modalLoading: false,
      TAX_RATE_OPTION,
      OTHER_TASK_NAME_ARRAY,
    };
  },
  filters: {
    formatAmount(v) {
      return parseFloat(v).toFixed(2);
    },
  },
  created() {
    this.setOriginData();
    this.setInvoiceTotalAmountHandle();
  },
  beforeDestroy() {
    document.onkeydown = undefined;
  },
  methods: {
    /**
    键盘对应的keyCode：
        0-9：48-57
        小键盘0-9：96-105
        a/A-y/Y：65-90
        ,：188
        ，：229
        小键盘.：110
        .：190
        enter：13
      */
    addScanMonitor() {
      let str = "";
      document.onkeydown = (event) => {
        if (event.keyCode !== 13) {
          if (
            (event.keyCode >= 48 && event.keyCode <= 57) ||
            (event.keyCode >= 96 && event.keyCode <= 105) ||
            (event.keyCode >= 65 && event.keyCode <= 90) ||
            [188, 229, 110, 190].includes(event.keyCode)
          ) {
            // 如果是小数点，统一转成，(中文的逗号)
            if ([229, 188].includes(event.keyCode)) {
              str += INVOICE_SPLIT_KEY;
            } else {
              str += event.key;
            }
          }
        } else {
          const scanValue = _.cloneDeep(str);
          const arr = scanValue.split(INVOICE_SPLIT_KEY);
          if (arr.length === INVOICE_SPLIT_LENGTH) {
            if (this.enabledParse) {
              const appLoading = this.appLoading("数据解析中...");
              try {
                this.handleInvoiceParse(scanValue);
              } finally {
                appLoading.close();
              }
            } else {
              this.msgError("请开启自动扫描");
            }
          }
          str = "";
        }
      };
    },
    onEnabledAutoParse(isEnable) {
      this.enabledParse = isEnable;
      if (isEnable) {
        this.addScanMonitor();
      }
    },
    setOriginData() {
      this.originData = _.cloneDeep(this.model);
    },
    setInvoiceTotalAmountHandle() {
      this.calculateInvoiceTotalAmountHandle(this.invoices);
    },
    formatAmount({ cellValue }) {
      return parseFloat(cellValue).toFixed(2);
    },
    /**
     * 发票解析
     */
    handleInvoiceParse(scanFrameValue) {
      const reg = /^(\d{4})(\d{2})(\d{2})$/;
      if (
        typeof scanFrameValue === "string" &&
        scanFrameValue.trim().length > 0
      ) {
        const arr = scanFrameValue.split(INVOICE_SPLIT_KEY);
        if (arr.length !== INVOICE_SPLIT_LENGTH) {
          this.msgError("解析失败，无效的发票数据【" + scanFrameValue + "】");
        } else {
          const invoiceNum = arr[3];
          const amount = arr[4];
          if (typeof amount === "string" && amount.trim().length > 0) {
            const pass = this.addInvoiceNumCheck(invoiceNum);
            if (!pass) {
              this.msgError("添加失败，发票号码【" + invoiceNum + "】已存在");
            } else {
              let invoices = _.cloneDeep(this.invoices) || [];
              invoices.unshift(
                Object.assign(
                  {},
                  {
                    invoiceCode: arr[2],
                    invoiceNum: arr[3],
                    invoiceDate: arr[5].replace(reg, "$1-$2-$3"),
                    invoiceAmount: amount + amount * this.taxRate,
                    taxRate: this.taxRate,
                    remark: undefined,
                  }
                )
              );
              this.$emit("onChange", _.cloneDeep(invoices));
              this.calculateInvoiceTotalAmountHandle(invoices);
              this.resetInvoiceForm();
            }
          } else {
            this.msgError("解析失败，无效的发票金额【" + amount + "】");
          }
        }
      } else {
        this.msgError("解析失败，无效的发票数据");
      }
    },
    handleDupInvoiceCheck() {
      const invoices = _.cloneDeep(this.invoices);
      if (Array.isArray(invoices)) {
        const invoiceNums = _.compact(
          invoices.map((item) => {
            if (item.invoiceNum) {
              return item.invoiceNum;
            }
          })
        );
        if (invoiceNums.length > 0) {
          const appLoading = this.appLoading();
          request({
            headers: { "Content-Type": "application/json" },
            url: "/eip/reimbursement/getInvoices/" + invoiceNums,
            method: "get",
          })
            .then((invoiceArr) => {
              const map = new Map();
              if (Array.isArray(invoiceArr)) {
                invoiceArr.forEach((item) => {
                  map.set(item.invoiceNum, item);
                });
              }
              if (this.pageAction === "edit") {
                if (
                  this.originData &&
                  Array.isArray(this.originData.invoices)
                ) {
                  const originInvoices = this.originData.invoices;
                  const originDataNums = originInvoices.map((item) => {
                    return item.invoiceNum;
                  });
                  invoices.forEach((i) => {
                    if (
                      map.get(i.invoiceNum) &&
                      originDataNums.indexOf(i.invoiceNum) === -1
                    ) {
                      i.isRepetitionInvoiceNum = true;
                    } else {
                      i.isRepetitionInvoiceNum = false;
                    }
                  });
                }
              } else {
                invoices.forEach((i) => {
                  if (map.get(i.invoiceNum)) {
                    i.isRepetitionInvoiceNum = true;
                  } else {
                    i.isRepetitionInvoiceNum = false;
                  }
                });
              }
              this.$emit("onChange", _.cloneDeep(invoices));
            })
            .catch(() => {
              this.msgError("重复发票核验失败");
            })
            .finally(() => {
              appLoading.close();
            });
        }
      }
    },
    onAdd() {
      this.addInvoiceModel = COMMON_ADD_INVOICE_MODEL;
      this.isEdit = false;
      this.modalVisible = true;
    },
    onQuickAdd() {
      this.addInvoiceModel = QUICK_ADD_INVOICE_MODEL;
      this.isEdit = false;
      this.modalVisible = true;
    },
    onRemoveInvoice(rowIndex) {
      const invoices = _.cloneDeep(this.invoices) || [];
      if (Array.isArray(invoices) && invoices.length > rowIndex) {
        invoices.splice(rowIndex, 1);
        this.$emit("onChange", invoices);
        this.calculateInvoiceTotalAmountHandle(invoices);
      }
    },
    onEditInvoice(row, rowIndex) {
      this.addInvoiceModel = COMMON_ADD_INVOICE_MODEL;
      this.invoiceModel = Object.assign({}, row);
      this.beforeEditInvoice = Object.assign({}, row);
      this.isEdit = true;
      this.editRowIndex = rowIndex;
      this.modalVisible = true;
    },
    /**
     * 发票清单-弹窗confirm
     */
    onModalConfirm() {
      this.invoiceFormValid(() => {
        const invoiceNum = this.invoiceModel.invoiceNum;
        const originalNum = (this.beforeEditInvoice || {}).invoiceNum;
        const pass = this.isEdit
          ? this.editInvoiceCheck(originalNum, invoiceNum)
          : this.addInvoiceNumCheck(invoiceNum);
        if (!pass) {
          this.msgError("添加失败，发票号码【" + invoiceNum + "】已存在");
        } else {
          this.transformInvoiceInfo(this.invoiceModel, this.isEdit);
          this.onModalCancel();
        }
      });
    },
    /**
     * 发票清单-模态框表单校验
     */
    invoiceFormValid(validSuccessCallback) {
      this.$refs["invoiceFormRef"].validate((valid) => {
        if (valid) {
          if (Util.isFunction(validSuccessCallback)) {
            validSuccessCallback();
          }
        }
      });
    },
    transformInvoiceInfo(invoiceModel, isEdit = false) {
      let invoices = _.cloneDeep(this.invoices) || [];
      if (isEdit) {
        invoices[this.editRowIndex] = Object.assign({}, invoiceModel);
        // 重置重复发票编号标识
        if (
          invoices[this.editRowIndex].isRepetitionInvoiceNum &&
          invoiceModel.invoiceNum &&
          (this.beforeEditInvoice || {}).invoiceNum !== invoiceModel.invoiceNum
        ) {
          invoices[this.editRowIndex].isRepetitionInvoiceNum = false;
        }
      } else {
        // 填充税率、更新发票金额
        const invoiceAmount = invoiceModel.invoiceAmount;
        invoiceModel.invoiceAmount =
          invoiceAmount + invoiceAmount * this.taxRate;
        invoiceModel.taxRate = this.taxRate;
        invoices.unshift(Object.assign({}, invoiceModel));
      }
      this.$emit("onChange", invoices);
      this.calculateInvoiceTotalAmountHandle(invoices);
    },
    /**
     * 统计发票总金额
     */
    calculateInvoiceTotalAmountHandle(invoices) {
      let total = 0;
      if (Array.isArray(invoices) && invoices.length > 0) {
        total = invoices.reduce((total, item) => {
          return (
            Number.parseFloat(total) + Number.parseFloat(item.invoiceAmount)
          );
        }, 0);
      }
      this.invoiceTotalAmount = total;
    },
    formatDate({ cellValue }) {
      return formatter.formatDate(cellValue);
    },
    resetInvoiceForm() {
      this.invoiceModel = {
        invoiceCode: undefined,
        invoiceNum: undefined,
        invoiceDate: undefined,
        invoiceAmount: undefined,
        taxRate: TAX_RATE_DEFAULT_VALUE,
        remark: undefined,
      };
      if (this.$refs["invoiceFormRef"]) {
        this.$refs["invoiceFormRef"].clearValidate();
      }
    },
    /**
     * 发票清单-弹窗 取消/关闭
     */
    onModalCancel() {
      this.modalVisible = false;
      this.resetInvoiceForm();
    },
    /**
     * 发票清单-模态框close回调
     */
    onModalClose() {
      this.resetInvoiceForm();
    },
    /**
     * 发票清单-模态框show回调
     */
    onModalShow() {
      this.onInvoiceNumInputFocus();
    },
    /**
     * 发票清单-模态框，发票金额聚焦
     */
    onInvoiceNumInputFocus() {
      if (
        this.addInvoiceModel === QUICK_ADD_INVOICE_MODEL &&
        this.$refs["invoiceNumRef"]
      ) {
        this.$refs["invoiceNumRef"].focus();
      }
    },
    changeTaxRate(rate, row) {
      const amount = row.invoiceAmount / (1.0 + (row.taxRate || 0));
      row.invoiceAmount = amount * (1.0 + rate);
      row.taxRate = rate;
    },
    /**
     * 发票清单-模态框，发票金额entity事件
     */
    onInvoiceAmountEntity() {
      if (this.addInvoiceModel === QUICK_ADD_INVOICE_MODEL) {
        this.invoiceFormValid(() => {
          const invoiceNum = this.invoiceModel.invoiceNum;
          const pass = this.addInvoiceNumCheck(invoiceNum);
          if (!pass) {
            this.msgError("添加失败，发票号码【" + invoiceNum + "】已存在");
          } else {
            this.transformInvoiceInfo(this.invoiceModel, this.isEdit);
            this.resetInvoiceForm();
            this.onInvoiceNumInputFocus();
          }
        });
      }
    },
    addInvoiceNumCheck(invoiceNum) {
      let pass = true;
      if (typeof invoiceNum === "string" && invoiceNum.trim().length > 0) {
        let invoices = _.cloneDeep(this.invoices) || [];
        const invoiceNums = invoices.map((item) => item.invoiceNum) || [];
        pass = !invoiceNums.includes(invoiceNum);
      }
      return pass;
    },
    editInvoiceCheck(originalNum, invoiceNum) {
      let pass = true;
      if (typeof invoiceNum === "string" && invoiceNum.trim().length > 0) {
        if (originalNum !== invoiceNum) {
          pass = this.addInvoiceNumCheck(invoiceNum);
        }
      }
      return pass;
    },
  },
};
</script>
